updateTracker = function () {
	var DEFAULT_UPDATE_INTERVAL = 5;
	var MAX_UPDATE_INTERVAL = 30;
	var counter = DEFAULT_UPDATE_INTERVAL;
	var fetches = 0;
	var getNewInterval = function () {
		var x = DEFAULT_UPDATE_INTERVAL + (fetches - fetches % 20) / 20;
		if (x > MAX_UPDATE_INTERVAL) {
			x = MAX_UPDATE_INTERVAL;
		}
		return x;
	};

	return {
		interval: DEFAULT_UPDATE_INTERVAL,
		
		reset: function () {
			fetches = 0;
			if (counter > DEFAULT_UPDATE_INTERVAL) {
				counter = DEFAULT_UPDATE_INTERVAL;
			}
		},
		
		needFetch: function () {
			return --counter < 1;
		},
		
		fetch: function () {
			fetches++;
			this.interval = getNewInterval();
	    	counter = this.interval;
		},
		
		start: function (fetchFunc) {
			object = this;
	    	$.timer(1000, function (timer) {
	    		if (object.needFetch()) {
					fetchFunc();
	    			object.fetch();
	    		}
 			});			
		}
	}
} ();

chatBuilder = function () {
	var russian = 'абвгдеёжзийклмнопрстуфхцчшщьъыэюя';
	var english = 'abcdefghijklmnopqrstuvwxyz';

	var liClassName = function (cls) {
		var s = ' class="item';
		s += cls != null ? ' ' + cls: '';
		return s + '" ';
	};
	
	var messageClassName = function (cls) {
		return cls != null ? ' class="' + cls + '" ': '';	
	};

	var liIdName = function (key) {
		return key != null ? " id='" + key + "' " : "";
	};	
	
	var cntChars = function (word, set) {
		var cnt = 0;
		for (var i = 0; i < word.length; ++i) {
			if (set.indexOf(word[i].toLowerCase()) != -1) {
				cnt++;
			}
		}	
		return cnt;
	};
	
	var messageProcessor = function (text) {
		if (text.length > 1 && text.charAt(0) == '→')	{
			text = '<img class="notify" src="/static/images/to.gif"/>' + text.substring(1);
		}
		return text;
	};
	
	var getProperNickname = function (nick) {
		var cntRu = cntChars(nick, russian);
		var cntEn = cntChars(nick, english);
		if (cntEn && cntRu) {
			var newNick = '';
			for (var i = 0; i < nick.length; ++i) {
				if (russian.indexOf(nick[i].toLowerCase()) != -1) {
					if (cntRu <= cntEn) {
						newNick += '<span class="ru">' + nick[i] + '</span>';
					} else {
						newNick += nick[i];
					}
				} else if (english.indexOf(nick[i].toLowerCase()) != -1) {
					if (cntEn <= cntRu) {
						newNick += '<span class="en">' + nick[i] + '</span>';
					} else {
						newNick += nick[i];
					}
				} else {
					newNick += nick[i];
				}
			}
			return newNick;
		} else {
			return nick;	
		}
	};
	
	return {
		add: function (key, nickname, message, cls) {
			var s = '<li ' + liIdName(key) + liClassName(cls) + '><span class="nick">' +
					 getProperNickname(nickname) + '</span> ' + messageProcessor(message) + '</li>';
			$("#list ul").prepend(s);
		}
	}
} ();

submit = function () {
	var blocked = false;
	var showMessage = function (message) {
		var errorBox = $("#comment .error");	
		errorBox.text(message);
		errorBox.show();
		setTimeout(function () {
			errorBox.hide()
		}, 5000);		
	};
	var analyseMessage = function (message) {
		if (/^\s*$/.test(message)) {
			return "Введите текст.";
		}
		if (message.length > 400) {
			return "Очень большое сообщение."
		}
		return "";
	};	
	
	return {
		handler: function () {
			if (blocked) {
				showMessage("Не флудим так часто :)");
			} else {
				var message = $('#new_comment').val();
				var analyseResult = analyseMessage(message);
				if (analyseResult == "") {
					/* send message */
					$.ajax({
					    url: '/',
					    data:{text:message},
					    type: 'POST',
						cache:false
					});		
							
					updateTracker.reset();

					/* clear input */
					$('#new_comment').val('');

					/* add this message to list */			
					chatBuilder.add(null, $('#nickname').text(), message, "me");

					/* prevent multiple messages from single user */
					blocked = true;
					setTimeout(function () {
						blocked = false;
					}, 2000);
				} else {
					showMessage(analyseResult);
				}
			}
			return false;
		}
	};
} ();

jsonMessagesParser = function () {
	var additionalClass = function (item, nickname) {
		var reg = new RegExp('→' + nickname);
		if (reg.test(item.text)) {
			return "notify";
		}
		if (item.nickname == nickname) {
			return "me";
		}
		return null;
	};
	
	var run = function (json, init) {
		var nickname = $('#nickname').text();
		$.each(json.messages.reverse(), function (index, item) {
			/* do not add/del my messages, except on init stage */
			if (init || nickname != item.nickname) {
				var messageElement = $('#' + item.key);
				if (!messageElement.length && !item.is_blocked) {
					chatBuilder.add(item.key, item.nickname,  item.text, additionalClass(item, nickname));
				}
				if (messageElement.length && item.is_blocked) {
					messageElement.hide();
				}
			}
		});	
	};
	
	return {
		init: function (json) {
			run(json, true);
		},
		update: function (json) {
			run(json, false);
		}
	}
} ();
/*
nicknameChooser = function() {
	var click = function () {
		$('#new_nickname').val('');
		$('#change_nick').show();
		$('#new_nickname').focus();
		return false;		
	};
	var cancel = function () {
		$('#change_nick').hide();
		return false;
	};
	var change = function (e) {
    	var nickname = $('#new_nickname').val();
    	$('#change_nick img').show();
    	$.ajax({
	    	url: '/change',
	    	dataType:'json',
	    	data: {'nickname': nickname},
	    	success: nicknameChooser.processResult,
			cache:false
		});
    	return false;
	};
	var success = function () {
		location.reload();
	};
	var failure = function () {
		var errorBox = $('#change_nick .error');
		errorBox.show(); 
		setTimeout(function() {
			errorBox.hide()
		}, 5000);   
		$('#new_nickname').focus();	
	};
	
	return {
		processResult: function (json) {
			$('#change_nick img').hide();
			json.result ? success() : failure();
		},
		
		init: function () {
			$('#comment a').click(click);
			$('#change_nick form').submit(change);
			$('#change_nick .cancel').click(cancel);
			$('#change_nick .apply').click(change);
		}
	}
} (); */

jQuery(document).ready(function() {
	/* load inital messages */
	$.ajax({
	    url: '/init',
	    dataType:'json',
	    success: function (json) { 
	    	$('#loader').remove();
	    	jsonMessagesParser.init(json);
			updateTracker.start(fetchMessages);
	    },
		cache:false
	});	
	
	$('#comment form').bind('submit', submit.handler);
	 	
 	$('.nick').live('click', function (e) {
		var selected_nickname = $(e.target).text();
		var your_nickname = $('#nickname').text();
		if (your_nickname != selected_nickname) {
			var inputField = $("#new_comment");
			inputField.focus();
			inputField.val("→" + selected_nickname + " ");
		}
	});
	
	var fetchMessages = function () {
		$.ajax({
		    url: '/live',
		    dataType:'json',
		    data:{'interval': updateTracker.interval},
		    success: jsonMessagesParser.update,
			cache:false
		});
	}
});
